package com.healthdata.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.healthdata.dao.UserApplicationMapper;
import com.healthdata.dao.UserMapper;
import com.healthdata.entity.User;
import com.healthdata.entity.UserApplication;
import com.healthdata.service.UserService;
import com.healthdata.util.JwtUtil;
import com.healthdata.vo.UserApplicationVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j  // 添加这个注解
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserApplicationMapper userApplicationMapper;

    @Autowired
    public UserServiceImpl(UserMapper userMapper,
                           PasswordEncoder passwordEncoder,
                           JwtUtil jwtUtil) {
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
        this.jwtUtil = jwtUtil;
    }

    @Override
    public User getByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public boolean register(User user) {
        User existUser = getByUsername(user.getUsername());
        if (existUser != null) {
            return false;
        }

        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setStatus(1);

        return save(user);
    }

    private Map<Long, String> userTokenMap = new HashMap<>();

    public String login(String username, String password) {
        // 直接从数据库查询最新用户信息，避免缓存问题
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            return null;
        }

        // 调试日志：打印输入密码和存储的哈希密码
        log.debug("Login attempt - username: {}, input password: {}, stored hash: {}",
                username, password, user.getPassword());

        // 验证密码
        if (!passwordEncoder.matches(password, user.getPassword())) {
            return null;
        }

        // 生成新token
        Long userId = user.getId();
        String newToken = jwtUtil.generateToken(userId);
        userTokenMap.put(userId, newToken);

        return newToken;
    }


    @Override
    public boolean resetPassword(String username, String email,String newPassword) {
        User user = userMapper.selectByUsername(username);
        if (user == null || !user.getEmail().equals(email)) {
            return false;
        }
        user.setPassword(newPassword);
        user.setUpdateTime(new Date());

        boolean updated = this.updateById(user);

        if (updated) {
            userTokenMap.remove(user.getId());
        }

        return updated;
    }


    @Override
    public boolean updateById(User user) {
        User existingUser = getById(user.getId());
        if (existingUser != null) {
            user.setRole(existingUser.getRole()); // 禁止修改角色
        }
        user.setUpdateTime(new Date());
        if (user.getPassword() != null) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        return super.updateById(user);
    }

    @Override
    public List<User> getAllUsers() {
        return this.list();
    }

    @Override
    public boolean submitApplication(UserApplication application) {
        application.setStatus("未处理");
        application.setApplyTime(new Date());
        return userApplicationMapper.insert(application) > 0;
    }

    @Override
    public List<UserApplicationVO> getUserApplication(Long userId) {
        List<UserApplication> applications = userApplicationMapper.selectByUserId(userId);
        return applications.stream()
                .map(application -> {
                    User user = userMapper.selectById(application.getUserId());
                    return convertToUserApplicationVO(application, user);
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<UserApplicationVO> getAllApplications() {
        List<UserApplication> applications = userApplicationMapper.selectAll();
        return applications.stream()
                .map(application -> {
                    User user = userMapper.selectById(application.getUserId());
                    return convertToUserApplicationVO(application, user);
                })
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean handleApplication(Long applicationId, boolean isApproved) {
        UserApplication application = userApplicationMapper.selectById(applicationId);
        if (application == null) {
            return false;
        }
        if (isApproved) {
            User user = userMapper.selectById(application.getUserId());
            if (user != null) {
                user.setRole(User.ROLE_AUDITOR);
                userMapper.updateById(user);
                application.setStatus("同意");
            }
        } else {
            application.setStatus("拒绝");
        }
        application.setHandleTime(new Date());
        return userApplicationMapper.updateById(application) > 0;
    }

    @Override
    public UserApplication getApplicationById(Long applicationId) {
        return userApplicationMapper.selectById(applicationId);
    }

    @Override
    public boolean updateApplication(UserApplication application) {
        return userApplicationMapper.updateById(application) > 0;
    }

    @Override
    public List<UserApplicationVO> getAllAuditorApplications() {
        List<UserApplication> applications = userApplicationMapper.selectAll();
        return applications.stream()
//                .filter(app -> "AUDITOR".equals(app.getTargetRole()) && app.getStatus().startsWith("未处理"))
                .filter(app -> "AUDITOR".equals(app.getTargetRole()))
                //不管是否处理，都返回
                .map(this::convertToUserApplicationVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<UserApplicationVO> getAllAdminApplications() {
        List<UserApplication> applications = userApplicationMapper.selectAll();
        return applications.stream()
//                .filter(app -> "ADMIN".equals(app.getTargetRole()) && app.getStatus().startsWith("未处理"))
                .filter(app -> "ADMIN".equals(app.getTargetRole()))   //不管是否处理，都返回
                .map(this::convertToUserApplicationVO)
                .collect(Collectors.toList());
    }

    private UserApplicationVO convertToUserApplicationVO(UserApplication application) {
        UserApplicationVO vo = new UserApplicationVO();
        vo.setId(application.getId());
        vo.setUserId(application.getUserId());
        User user = this.getById(application.getUserId());
        if (user != null) {
            vo.setUsername(user.getUsername());
        }
        vo.setReason(application.getReason());
        vo.setStatus(application.getStatus());
        vo.setApplyTime(application.getApplyTime());
        vo.setHandleTime(application.getHandleTime());
        vo.setAdminReply(application.getAdminReply());
        vo.setTargetRole(application.getTargetRole()); // 设置 targetRole
        return vo;
    }

    private UserApplicationVO convertToUserApplicationVO(UserApplication application, User user) {
        UserApplicationVO vo = new UserApplicationVO();
        vo.setId(application.getId());
        vo.setUserId(application.getUserId());
        vo.setUsername(user.getUsername());
        vo.setReason(application.getReason());
        vo.setStatus(application.getStatus());
        vo.setApplyTime(application.getApplyTime());
        vo.setHandleTime(application.getHandleTime());
        vo.setAdminReply(application.getAdminReply());
        vo.setTargetRole(application.getTargetRole()); // 设置 targetRole
        return vo;
    }

}